package com.paul.web.security;

import com.paul.common.constant.RedisKeyConst;
import com.paul.jwt.JWTUtil;
import com.paul.jwt.config.JwtConfig;
import com.paul.jwt.dto.AuthPrincipal;
import com.paul.redis.utils.RedisUtil;
//import com.paul.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

@Component
public class JWTAuthenticationManager implements AuthenticationManager {

    @Autowired
    private JwtConfig jwtConfig;

    @Autowired
    private RedisUtil redisUtil;

//    @Autowired
//    private ISysMenuService sysMenuService;

    /**
     * 进行token鉴定
     *
     * @param authentication 待鉴定的JWTAuthenticationToken
     * @return 鉴定完成的JWTAuthenticationToken，供Controller使用
     * @throws AuthenticationException 如果鉴定失败，抛出
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//        System.out.println("====执行authenticate方法====");
        String token = authentication.getCredentials().toString();

        AuthPrincipal authPrincipal = JWTUtil.getAuthUser(token);

        if (authPrincipal == null) {
            throw new UsernameNotFoundException("invalid token");
        }

        /*
         * 官方推荐在本方法中必须要处理三种异常，
         * DisabledException、LockedException、BadCredentialsException
         * 这里为了方便就只处理了BadCredentialsException，大家可以根据自己业务的需要进行定制
         * 详情看AuthenticationManager的JavaDoc
         */
        boolean isAuthenticatedSuccess = JWTUtil.verify(authPrincipal, token, jwtConfig);
        if (!isAuthenticatedSuccess) {
            throw new BadCredentialsException(" authentication failed");
        }

        String strUserPermission = null;

        // 普通权限，非细粒度认证
        if (authPrincipal.getSysAuthType() == 0) {
            strUserPermission = "";
        }
        // 角色权限
        if (authPrincipal.getSysAuthType() == 1) {
            Object userPermissionsObj = redisUtil.get(RedisKeyConst.USER_PERMI_SSION + authPrincipal.getUserId());
            if (userPermissionsObj == null) {
//                List<String> permissionList = sysMenuService.getRolePermission(authPrincipal.getRoleId(), authPrincipal.getIsAdmin(), authPrincipal.getTenantId());
//                strUserPermission = StringUtils.join(permissionList, ",");
//            System.out.println("strUserPermission:" + StringUtils.join(permissionList, ","));
                redisUtil.set(RedisKeyConst.USER_PERMI_SSION + authPrincipal.getUserId(), strUserPermission);
            } else {
                strUserPermission = userPermissionsObj.toString();
            }
        }

        return new JWTAuthenticationToken(
                token, authPrincipal, AuthorityUtils.commaSeparatedStringToAuthorityList(strUserPermission));
    }
}

